package com.project.web.admin.utils.shiro.redis;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yun.common.utils.ByteUtil;
import org.yun.common.utils.redis.RedisClient;
import org.yun.common.utils.redis.RedisConsts;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class ShiroRedisSessionDAO extends AbstractSessionDAO {

    private static Logger logger = LoggerFactory.getLogger(ShiroRedisSessionDAO.class);

    //注入redisClient实例
    @Resource(name = "redisClient")
    private RedisClient redisClient;

    /**
     * shiro-redis的session对象前缀
     */
    private String keyPrefix = RedisConsts.ADMIN_SHIRO_SESSION_KEY;

    @Override
    public void update(Session session) throws UnknownSessionException {
        this.saveSession(session);
    }

    private void saveSession(Session session) throws UnknownSessionException {
        if (session == null || session.getId() == null) {
            logger.error("session or session id is null");
            return;
        }
        this.redisClient.setAndExpire(this.getPreStringKey(session.getId()), session, RedisConsts.ADMIN_SHIRO_SESSION_EXPIRE);
    }

    @Override
    public void delete(Session session) {
        if (session == null || session.getId() == null) {
            logger.error("session or session id is null");
            return;
        }
        redisClient.del(getPreStringKey(session.getId()));

    }

    @Override
    public Collection<Session> getActiveSessions() {
        Set<Session> sessions = new HashSet<Session>();

        Set<byte[]> keys = null;
        try {
            keys = redisClient.keys(ByteUtil.objectToBytes(this.keyPrefix + "*"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (keys != null && keys.size() > 0) {
            for (byte[] key : keys) {
                Session s = null;
                try {
                    s = (Session) ByteUtil.bytesToObject(redisClient.get(key));
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                sessions.add(s);
            }
        }

        return sessions;
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        this.assignSessionId(session, sessionId);
        this.saveSession(session);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        if (sessionId == null) {
            logger.error("session id is null");
            return null;
        }

        Session s = (Session) redisClient.get(this.getPreStringKey(sessionId));
        return s;
    }

    /**
     * 获得String类型的key
     *
     * @param
     * @return
     */
    private String getPreStringKey(Serializable sessionId) {
        String preKey = this.keyPrefix + sessionId;
        return preKey;
    }

    public String getKeyPrefix() {
        return keyPrefix;
    }

    public void setKeyPrefix(String keyPrefix) {
        this.keyPrefix = keyPrefix;
    }

    public void setRedisClient(RedisClient redisClient) {
        this.redisClient = redisClient;
    }

    public RedisClient getRedisClient() {
        return redisClient;
    }

}
